package de.g18.scavengerhunt.types;

import java.security.InvalidParameterException;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.Overlay;

import de.g18.scavengerhunt.AppApplicationContext;
import de.g18.scavengerhunt.overlay.CircleOverlay;
import de.g18.scavengerhunt.utils.GameUtils;

/**
 *  This object defines the battle zone and supplies methods, to draw it correctly
 */
public class BattleZone {

    private String        name           = "";

    private int           radiusInMeters = 0;

    private GeoPoint      circleCenter   = null;

    private CircleOverlay circleOverlay  = null;

    public BattleZone() {
        this.circleOverlay = new CircleOverlay(AppApplicationContext.getCurrentActivity());
    }

    public BattleZone(GeoPoint circleCenter, int radiusInMeters) {
        this.setCircleCenter(circleCenter);
        this.setRadiusInMeters(radiusInMeters);
        this.circleOverlay = new CircleOverlay(AppApplicationContext.getCurrentActivity(), this.circleCenter, this.radiusInMeters);
    }

    public Overlay getCircleOverlay() {
        return this.circleOverlay;
    }

    public void setRadiusInMeters(int radiusInMeters) {
        if (radiusInMeters < 0 || radiusInMeters > 10000) {
            throw new InvalidParameterException();
        }
        this.radiusInMeters = radiusInMeters;

        if (this.circleOverlay != null) {
            this.circleOverlay.setRadius(radiusInMeters);
        }
    }

    public void setCircleCenter(GeoPoint circleCenter) {
        if (circleCenter == null) {
            throw new InvalidParameterException();
        }
        this.circleCenter = circleCenter;

        if (this.circleOverlay != null) {
            this.circleOverlay.setGeoPoint(this.circleCenter);
        }
    }

    /**
     * Calculates and returns the needed zoom level to fit the area of the game on screen.
     * 
     * @return int
     */
    public int getZoomLevelToFitZone(double widthInPixels) {
        double equatorLengthInMeters = 40075004;
        double metersPerPixel = equatorLengthInMeters / 256;
        int zoomLevel = 1;
        while ((metersPerPixel * widthInPixels) > radiusInMeters) {
            metersPerPixel /= 2;
            ++zoomLevel;
        }
        if (zoomLevel - 2 >= 1) {
            zoomLevel -= 2;
        }
        return zoomLevel;
    }

    /**
     * Checks if a User is in the BattleZone.
     * 
     * @param user
     * @return boolean
     */
    public boolean isInBattleZone(User user) {
        int distance = GameUtils.getDistanceBetweenPoints(this.circleCenter, user.getCurrentGeoPoint());
        if (distance <= radiusInMeters) {
            return true;
        } else {
            return false;
        }
    }

    public GeoPoint getCircleCenter() {
        return this.circleCenter;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public int getRadiusInMeters() {
        return this.radiusInMeters;
    }
}